package org.ting.e_commerce.utils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

import static java.lang.Thread.sleep;

class Code {
    private int code;
    private long deadTime;
    public boolean isDead() {
        return System.currentTimeMillis() > deadTime;
    }
    public Code(int code, long deadTime) {
        this.code = code;
        this.deadTime = deadTime;
    }
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public long getDeadTime() {
        return deadTime;
    }

    public void setDeadTime(long deadTime) {
        this.deadTime = deadTime;
    }
}
public class EmailVerify {
    // 设置您的 QQ 邮箱地址和密钥
    public static final String username = "2275980533@qq.com";
    public static final String password = "ahlbhvokojtmdicd";
    public static final ConcurrentHashMap<String, Code> emailToCodeAndDeadTime = new ConcurrentHashMap<>();
    public static Properties props;

    public static Session session;

    static {
        // 配置邮件服务器属性
        props = new Properties();
        props.put("mail.smtp.host", "smtp.qq.com");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.starttls.enable", "true");

        // 创建会话对象
        session = Session.getInstance(props,
                new Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });

        //清理线程防止验证码生成过多
        new Thread(() -> {
            while(true) {
                try {
                    sleep(1000 * 60 * 10);
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                }
                for(Map.Entry<String, Code> entry : emailToCodeAndDeadTime.entrySet()) {
                    Code code = entry.getValue();
                    if (code.isDead()) {
                        emailToCodeAndDeadTime.remove(entry.getKey());
                    }
                }
            }
        }).start();
    }

    public static synchronized void send(String email, String text) throws MessagingException {
        // 创建邮件消息
        Message message = new MimeMessage(session);
        try {
            message.setFrom(new InternetAddress(username));
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse(email));
        message.setSubject("验证码！");
        message.setText("您的验证码是：" + text + " 五分钟内有效");
        // 发送邮件
        Transport.send(message);
    }
    public static String verify(String email, int emailCode) {
        try {
            Code code = emailToCodeAndDeadTime.get(email);
            if(code.isDead()) {
                return "验证码已失效或还未获取";
            }
            if(code.getCode() == emailCode) {
                emailToCodeAndDeadTime.remove(email);
                return "success";
            }
            return "验证码错误";
        }catch (NullPointerException e) {
            return "验证码已失效或还未获取";
        }

    }
    public static synchronized String sendCode(String email) {
        //防止获取过于频繁，生成最小间隔1分钟
        try{
            long deadTime = emailToCodeAndDeadTime.get(email).getDeadTime();
            if(deadTime > System.currentTimeMillis() + 1000 * 60 * 4) {
                return "获取过于频繁请稍后再试";
            }
        }catch (NullPointerException e){
            //还没有生成过验证码
        }

        //生成6位验证码
        Random random = new Random();
        int min = 100000;
        int max = 999999;
        int randomNumber = random.nextInt(max - min + 1) + min;
        //设置有效时间，5分钟内有效
        long deadTime = System.currentTimeMillis() + 1000 * 60 * 5;
        emailToCodeAndDeadTime.put(email, new Code(randomNumber, deadTime));
        //发送验证码
        try {
            send(email, String.valueOf(randomNumber));
        } catch (MessagingException e) {
            return "邮箱地址有误";
        }
        return "success";
    }

}
